//==============================================================================
// Copyright (c) 2008-2013 Niall Ryan. All Rights Reserved.
//==============================================================================

#ifndef HYDRA_ALLOCATORS_BASICALLOCATOR_H
#define HYDRA_ALLOCATORS_BASICALLOCATOR_H 1

#include <cstdlib>

namespace Hydra
{
	/**
	 * A basic implementation of an allocator, uses the standard malloc/free to allocate. Vulnerable to the ABA problem.
	 */
	class BasicAllocator
	{
	public:
        static const bool kAbaVulnerable = true;
        static const bool kAllowsDanglingPointers = false;

		static void* alloc(size_t numBytes)
		{
			return ::malloc(numBytes);
		}

		template<typename T>
		static T* create()
		{
			T* item = static_cast<T*>(alloc(sizeof(T)));
			new(item) T;
			return item;
		}

		template<typename T>
		static T* createArray(size_t numElements)
		{
			T* arr = static_cast<T*>(alloc(sizeof(T)*numElements));
			for (unsigned int i=0; i<numElements; ++i)
				new(&arr[i]) T;
			return arr;
		}

		static void free(void* ptr)
		{
			::free(ptr);
		}

		template<typename T>
		static void destroy(T* item)
		{
			item->~T();
			free(item);
		}

		template<typename T>
		static void destroyArray(T* arr, size_t numElements)
		{
			for (unsigned int i=0; i<numElements; ++i)
				arr[i].~T();
			free(arr);
		}
	};
}

#endif
